package com.ruoyi.tb.lmt.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.tb.lmt.domain.bo.TbMaterialBo;
import com.ruoyi.tb.lmt.domain.vo.TbMaterialVo;
import com.ruoyi.tb.lmt.domain.TbMaterial;
import com.ruoyi.tb.lmt.mapper.TbMaterialMapper;
import com.ruoyi.tb.lmt.service.ITbMaterialService;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.concurrent.ExecutionException;

/**
 * 物资基础资料Service业务层处理
 *
 * @author ruoyi
 * @date 2023-11-30
 */
@RequiredArgsConstructor
@Service
public class TbMaterialServiceImpl implements ITbMaterialService {

    private final TbMaterialMapper baseMapper;

    @Autowired
    private TbMaterialMapper tbMaterialMapper;

    @Autowired
    private ISysUserService sysUserService;

    /**
     * 查询物资基础资料
     */
    @Override
    public TbMaterialVo queryById(Long ID){
        return baseMapper.selectVoById(ID);
    }

    /**
     * 查询物资基础资料列表
     */
    @Override
    public TableDataInfo<TbMaterialVo> queryPageList(TbMaterialBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TbMaterial> lqw = buildQueryWrapper(bo);
        // 在这里添加根据 CreateTime 降序排序
        pageQuery.setOrderByColumn("createTime");
        pageQuery.setIsAsc("desc");

        Page<TbMaterialVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        for (TbMaterialVo vo : result.getRecords()) {
            if (StringUtils.isNotBlank(vo.getCreateBy())){
                SysUser sysUser = sysUserService.selectUserByUserName(vo.getCreateBy());
                if (sysUser!=null){
                    vo.setCreateByName(sysUser.getNickName());
                }
            }
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询物资基础资料列表
     */
    @Override
    public List<TbMaterialVo> queryList(TbMaterialBo bo) {
        LambdaQueryWrapper<TbMaterial> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<TbMaterial> buildQueryWrapper(TbMaterialBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TbMaterial> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getProductcode()), TbMaterial::getProductcode, bo.getProductcode());
        lqw.like(StringUtils.isNotBlank(bo.getProductname()), TbMaterial::getProductname, bo.getProductname());
        return lqw;
    }

    /**
     * 新增物资基础资料
     */
    @Override
    public Boolean insertByBo(TbMaterialBo bo) {
        TbMaterial add = BeanUtil.toBean(bo, TbMaterial.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setID(add.getID());
        }
        return flag;
    }

    /**
     * 修改物资基础资料
     */
    @Override
    public Boolean updateByBo(TbMaterialBo bo) {
        TbMaterial update = BeanUtil.toBean(bo, TbMaterial.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(TbMaterial entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除物资基础资料
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public void export(HttpServletRequest request, HttpServletResponse response) {
        // 创建一个Excel工作簿
        Workbook workbook = new XSSFWorkbook();

        // 创建一个工作表sheet
        Sheet sheet = workbook.createSheet("物资基础资料");

        // 创建标题行
        Row titleRow = sheet.createRow(0);

        // 定义标题行的列名
        String[] columnHeaders = {
            "物资编号", "物资名称", "规格型号", "计量单位", "数量", "备注"
        };

        // 设置单元格样式（可选）
        CellStyle headerStyle = workbook.createCellStyle();
        Font headerFont = workbook.createFont();
        headerFont.setBold(true);
        headerStyle.setFont(headerFont);

        // 创建标题行单元格并写入列名
        for (int i = 0; i < columnHeaders.length; i++) {
            Cell cell = titleRow.createCell(i);
            cell.setCellValue(columnHeaders[i]);
            cell.setCellStyle(headerStyle);
        }
        // 设置所有行高
        for(Row row : sheet){
            row.setHeightInPoints(20);
        }

        // 设置所有列宽
        for(Sheet sh : workbook){
            for(int i = 0; i < 300; i++){
                sh.setColumnWidth(i, 14 * 256);
            }
        }

        OutputStream os = null;
        try {
            os = response.getOutputStream();
            workbook.write(os);
            os.flush();
            //os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Map updateExcel(MultipartFile file) throws Exception {
        Map map = new HashMap();
        try {
        Workbook workbook = new XSSFWorkbook(file.getInputStream());

        Sheet sheet = workbook.getSheetAt(0);
        int lastRowIndex = sheet.getLastRowNum();
        Row row = null;


        for (int i = 2; i <= lastRowIndex; i++) {
            row = sheet.getRow(i);
            TbMaterial material = new TbMaterial();
            // 检查物资编号
            Cell productCodeCell = row.getCell(0);
            if (productCodeCell != null && productCodeCell.getCellType() == CellType.STRING) {
                String productCode = productCodeCell.getStringCellValue();
                if (productCode.length() <= 50) {
                    material.setProductcode(productCode);
                } else {
                    throw new DataImportException("物资编号超过50个字符限制");
                }
            } else {
                throw new DataImportException("物资编号为空或不是文本格式");
            }

            // 检查物资名称
            Cell productNameCell = row.getCell(1);
            if (productNameCell != null && productNameCell.getCellType() == CellType.STRING) {
                String productName = productNameCell.getStringCellValue();
                if (productName.length() <= 200) {
                    material.setProductname(productName);
                } else {
                    throw new DataImportException("物资名称超过200个字符限制");
                }
            } else {
                throw new DataImportException("物资名称为空或不是文本格式");
            }

            // 检查规格型号
            Cell specsCell = row.getCell(2);
            if (specsCell != null && specsCell.getCellType() == CellType.STRING) {
                String specs = specsCell.getStringCellValue();
                if (specs.length() <= 200) {
                    material.setSpecs(specs);
                } else {
                    throw new DataImportException("规格型号超过200个字符限制");
                }
            } else {
                // 规格型号可为空，无需抛出异常，可记录日志或设置默认值
                material.setSpecs("");
            }

            // 检查计量单位
            Cell unitsCell = row.getCell(3);
            if (unitsCell != null && unitsCell.getCellType() == CellType.STRING) {
                String units = unitsCell.getStringCellValue();
                if (units.length() <= 50) {
                    material.setUnits(units);
                } else {
                    throw new DataImportException("计量单位超过50个字符限制");
                }
            } else {
                // 计量单位可为空，无需抛出异常，可记录日志或设置默认值
                material.setUnits("");
            }

            // 检查数量
            Cell unitPriceCell = row.getCell(4);
            if (unitPriceCell != null && unitPriceCell.getCellType() == CellType.NUMERIC) {
                double unitPrice = unitPriceCell.getNumericCellValue();
                material.setUnitprice(BigDecimal.valueOf(unitPrice));
            } else {
                throw new DataImportException("数量不是有效的数字格式");
            }

            // 检查备注
            Cell remarkCell = row.getCell(5);
            if (remarkCell != null && remarkCell.getCellType() == CellType.STRING) {
                String remark = remarkCell.getStringCellValue();
                if (remark.length() <= 100) {
                    material.setRemark(remark);
                } else {
                    throw new DataImportException("备注超过100个字符限制");
                }
            } else {
                // 备注可为空，无需抛出异常，可记录日志或设置默认值
                material.setRemark("");
            }
            TbMaterial add = BeanUtil.toBean(material, TbMaterial.class);
            validEntityBeforeSave(add);
        }
    }catch(Exception e){
        throw new ExecutionException("批量添加操作失败"); // 抛出自定义异常

    }
        return map;
    }

    @Override
    public  List<TbMaterialVo> selectBySpecs(String specs) {
        return tbMaterialMapper.selectBySpecs(specs);
    }

    @Override
    public TbMaterialBo getByProductCode(String productcode) {

       return tbMaterialMapper.getByProductCode(productcode);
    }

    public class ExecutionException extends RuntimeException {
        public ExecutionException(String message) {
            super(message);
        }
    }

    // 自定义的数据导入异常类
    public static class DataImportException extends Exception {
        public DataImportException(String message) {
            super(message);
        }
    }
}
